home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1992-06-30 | 53.7 KB | 1,453 lines
C.S.M.P. Digest Sat, 16 May 92 Volume 1 : Issue 83 Today's Topics: What does SerSetBuf actually do? THINK C and UNIX stat() function How to turn File Sharing on? Mapping one color to another - help! refreshing a colour screen How to Get the Name of A File? Register variables in Think C 4.05 Problem De-allocating Memory in variable sized arrays The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly. These digests are available (by using FTP, account anonymous, your email address as password) in the pub/mac/csmp-digest directory on ftp.cs.uoregon. edu. This is also the home of the comp.sys.mac.programmer Frequently Asked Questions list. The last several issues of the digest are available from sumex-aim.stanford.edu as well. These digests are also available via email. Just send a note saying that you want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will automatically receive each new digest as it is created. The digest is a collection of articles from the internet newsgroup comp.sys. mac.programmer. It is designed for people who read c.s.m.p. semi-regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. (This means you can't post questions to the digest.) The articles in these digests are taken directly from comp.sys.mac.programmer. They are not edited; all articles included in this digest are in their original posted form. The only articles that are -not- included in these digests are those which didn't receive any replies (except those that give information rather than ask a question). All replies to each article are concatenated onto the original article in the order in which they were received. Article threads are not added to the digests until the last article added to the thread is at least one month old (this is to ensure that the thread is dead before adding it to the digests). Send administrative mail to mkelly@cs.uoregon.edu. ------------------------------------------------------- From: mvivino@helix.nih.gov (Mark A. Vivino) Subject: What does SerSetBuf actually do? Date: 9 Apr 92 13:15:04 GMT Organization: National Institutes of Health I understand how to use SerSetBuf, but I am a bit confused as to how data actually transfers to the buffer after you make the call. For example, when I make the call: SerialErr := SerSetBuf(SPInputRefNum, Ptr(InputbufP), BigBufferSize); I would assume that data starts tranfering out of the default 64 character hardware buffer and into the base adress of my Inputbuffer by using some sort of interrupt mechanism. I obviously do not make any calls to copy the data into my software created buffer, but the data gets to the buffer without any trouble. The actual tranfer mechanism is not discussed in IM, or I haven't seen it. If it is interrupts, then when do they occur? Not extremely important, but it's nice to know what goes on. Mark Vivino mvivino@helix.nih.gov +++++++++++++++++++++++++++ From: d88-jwa@hemul.nada.kth.se (Jon W{tte) Date: 9 Apr 92 20:34:30 GMT Organization: Royal Institute of Technology, Stockholm, Sweden .nih.gov> mvivino@helix.nih.gov (Mark A. Vivino) writes: I understand how to use SerSetBuf, but I am a bit confused as to how data actually transfers to the buffer after you make the call. For example, when I make the call: SerialErr := SerSetBuf(SPInputRefNum, Ptr(InputbufP), BigBufferSize); I would assume that data starts tranfering out of the default 64 character hardware buffer and into the base adress of my Inputbuffer by using some sort of interrupt mechanism. I obviously do not make any calls to copy the data into my software created buffer, but the data gets to the buffer without any trouble. The actual tranfer mechanism is not discussed in IM, or I haven't seen it. If it is interrupts, then when do they occur? Why should you look at the serial ports internal buffer. For all you know, the data there is XOR-ed with a large prime number... You get at the data using FSRead and FSWrite. Anyway, yes, the serial port chip generates an interrupt when it receives characters. Exactly when and how is hard to tell, since the circuitry changes between models. The IIfx and Q900 even have a separate CPU handling the serial ports ! - -- h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! +++++++++++++++++++++++++++ From: jmunkki@hila.hut.fi (Juri Munkki) Date: 12 Apr 92 08:45:05 GMT Organization: Helsinki University of Technology, Finland In article <1992Apr9.131504.19339@alw.nih.gov> mvivino@helix.nih.gov (Mark A. Vivino) writes: >I understand how to use SerSetBuf, but I am a bit confused as to how data >actually transfers to the buffer after you make the call. For >example, when I make the call: > > SerialErr := SerSetBuf(SPInputRefNum, Ptr(InputbufP), BigBufferSize); > >I would assume that data starts tranfering out of the default 64 character >hardware buffer and into the base adress of my Inputbuffer by using >some sort of interrupt mechanism. I obviously do not make any calls >to copy the data into my software created buffer, but the data gets >to the buffer without any trouble. The actual tranfer mechanism Most Macs have a 3 character hardware buffer. The IIfx might have something better, since it has a 6502 controlling the serial port. The default 64 byte serial buffer is a software buffer and SerSetBuf exists so that you can have something bigger than that. The terminal program that I'm using right now allows you to set this buffer size and I've found that I never have problems when I use a 16KB buffer. After you set the buffer, you no longer have to worry about it. Use _Read calls to read the data. There's no way to tell how the buffer is used, if it is used at all. All you know is that once you give the buffer to the serial driver, it has a better chance of not dropping characters. The serial port chip generates an interrupt when it has incoming data. This is when the characters are copied into the buffer. Don't worry about it. ____________________________________________________________________________ / Juri Munkki / Helsinki University of Technology / Wind / Project / / jmunkki@hut.fi / Computing Center Macintosh Support / Surf / Arashi / ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +++++++++++++++++++++++++++ From: oueichek@imag.fr (Ibaa Oueichek) Date: 15 Apr 92 12:43:36 GMT d88-jwa@hemul.nada.kth.se (Jon W{tte) writes: : .nih.gov> mvivino@helix.nih.gov (Mark A. Vivino) writes: : : I understand how to use SerSetBuf, but I am a bit confused as to how data : actually transfers to the buffer after you make the call. For : example, when I make the call: : : SerialErr := SerSetBuf(SPInputRefNum, Ptr(InputbufP), BigBufferSize); : : I would assume that data starts tranfering out of the default 64 character : hardware buffer and into the base adress of my Inputbuffer by using : some sort of interrupt mechanism. I obviously do not make any calls : to copy the data into my software created buffer, but the data gets : to the buffer without any trouble. The actual tranfer mechanism : is not discussed in IM, or I haven't seen it. If it is interrupts, then : when do they occur? : : Why should you look at the serial ports internal buffer. : For all you know, the data there is XOR-ed with a large prime number... : You get at the data using FSRead and FSWrite. : : Anyway, yes, the serial port chip generates an interrupt when it : receives characters. Exactly when and how is hard to tell, since : the circuitry changes between models. The IIfx and Q900 even have : a separate CPU handling the serial ports ! : I've had the oppurtunity to write a driver for the Z8530, this is the Serial Communications Controller used in the Mac (SCC). The serial IO drivers in the Mac provide Asynchronous communications, that means that the interrupts are generated once there is a character in the SCC input register (reciever). BTW, the "hardware" buffer is NOT 64 characters wide, it's 3 or 4 chars max. The 64 chars buffer is the standard buffer allocated by the system at the bootstrap. SerSetBuf just changes the pointers, that's why you don't have to worry about it. But pay attention about what you are doing, a big buffer can resist better against the overflows, but on the other side, you may recieve too many chars before you "notice" that you don't need them. I don't know about the IIfx and Q900, but normally when a separate CPU handles the serial communications, it doesn't change the interrupt moment (ie, there will always be an interrupt when the SCC has "matched" a character on the input serial line). It's not the CPU which is interrupted anymore but rather the auxiliary CPU. The aux CPU informes the main CPU using shared variables. : -- : h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! - -- Sham(u) ya tha (s)seif(u) lam yaghib(i) | Ibaa Oueichek. oueichek@imag.imag.fr Ya jamal(al) majd(i) fi(l) kutub(i) | LABORATOIRE BULL-IMAG Kablak(i) (t)tareekh(u) fi thulmaten | Grenoble. Baadak(i) staula ala (sh)shuhub(i) | --------------------------- From: bill@lhotse.ucar.edu Subject: THINK C and UNIX stat() function Date: 10 Apr 92 16:09:04 GMT Organization: High Altitude Observatory/NCAR, Boulder CO Does THINK C have an equivalent to the UNIX system library routine stat()? Basically, I need to determine the time a file was modified so I don't really need the full functionality of the UNIX stat() routine. Is there anything in the THINK C library, or perhaps the Mac toolbox that will provide this capability? Thanks in advance, - --Bill +++++++++++++++++++++++++++ From: e-sink@uiuc.edu (Eric W. Sink) Organization: University of Illinois at Urbana-Champaign Date: Fri, 10 Apr 1992 20:50:30 GMT In <1992Apr10.160904.14885@ncar.ucar.edu> bill@lhotse.ucar.edu writes: >Basically, I need to determine the time a file was modified... unsigned long GetFModDate(char *filename, short volrefnum, long dirID) { HFileParam k; Str255 nm; OSErr bad; strcpy((char *) nm, filename); c2pstr(nm); k.ioCompletion = NULL; k.ioNamePtr = nm; k.ioVRefNum = volrefnum; k.ioFDirIndex = 0; k.ioDirID = dirID; bad = PBHGetFInfo((HParmBlkPtr) & k, false); if (!bad) return k.ioFlMdDat; else return 0; } - -- Eric W. Sink, Spatial Analysis and Systems Team USACERL, P.O. Box 9005, Champaign, IL 61826-9005 1-800-USA-CERL x449, e-sink@uiuc.edu +++++++++++++++++++++++++++ From: roy@adeptsln.cts.com Date: 14 Apr 92 03:29:09 GMT Organization: Adept Solutions In article <1992Apr10.160904.14885@ncar.ucar.edu> bill@lhotse.ucar.edu writes: > Does THINK C have an equivalent to the UNIX system library routine stat()? > Basically, I need to determine the time a file was modified so I don't > really need the full functionality of the UNIX stat() routine. Is there > anything in the THINK C library, or perhaps the Mac toolbox that will > provide this capability? > > Thanks in advance, > --Bill Look in IM Vol II, under PBGetFInfo (page 115), this call gives you everything pertenant about the file, including creation & modification dates. - -- Roy Lovejoy | internet: roy@adeptsln.cts.com Head RGB Guy | AppleLink: adept Adept Solutions | CIS: 72447,1447 .................| dual certified developer: NeXT & Apple ;) --------------------------- From: casgrain@ERE.UMontreal.CA (Casgrain Philippe) Subject: How to turn File Sharing on? Date: 10 Apr 92 17:58:11 GMT Organization: Universite de Montreal I would like to know how to turn file sharing ON or OFF, not by using the Control Panel, but from within an application. There seems to be no mention of this in IM VI. Examples in Pascal would be appreciated, but I have a reading knowledge of C. Thanks in advance, Philippe Casgrain Casgrain@ERE.UMontreal.CA +++++++++++++++++++++++++++ From: d88-jwa@byse.nada.kth.se (Jon W{tte) Date: 10 Apr 92 23:26:21 GMT Organization: Royal Institute of Technology, Stockholm, Sweden .umontreal.ca> casgrain@ERE.UMontreal.CA (Casgrain Philippe) writes: I would like to know how to turn file sharing ON or OFF, not by using the Control Panel, but from within an application. There seems to be no mention of this in IM VI. OFF: Send a quit apple event to the File Sharing process. ON: LaunchApplication on the File Sharing extension. FindFolder, PBCatSearch, GetNextProcess, GetProcessInfo and the AE manager seems to be the parts you need. - -- h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! +++++++++++++++++++++++++++ From: lkimes@alshain.usc.edu (Lance 'Moof' Kimes) Date: 10 Apr 1992 19:23:15 -0700 Organization: University of Southern California, Los Angeles, CA In article <D88-JWA.92Apr11002621@byse.nada.kth.se>, d88-jwa@byse.nada.kth.se (Jon W{tte) writes: |> .umontreal.ca> casgrain@ERE.UMontreal.CA (Casgrain Philippe) writes: |> |> I would like to know how to turn file sharing ON or OFF, not by |> using the Control Panel, but from within an application. |> There seems to be no mention of this in IM VI. |> |> OFF: Send a quit apple event to the File Sharing process. |> ON: LaunchApplication on the File Sharing extension. |> |> FindFolder, PBCatSearch, GetNextProcess, GetProcessInfo and the |> AE manager seems to be the parts you need. |> |> -- |> h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! Have you tried this to see if it works? It seems to me to be both very useful & full of potential security hazards. I know all users should be setup already with names & passwords, but what about hte clueless who are not? Even if everythings passworded, sharing could be turned on AGAINST your wishes & compromised passwords then allow easy entry. I guess we're just paranoid at USC, but we're safe. :-) Lance Kimes USC +++++++++++++++++++++++++++ From: lsr@taligent.com (Larry Rosenstein) Date: 13 Apr 92 18:32:22 GMT Organization: Taligent, Inc. In article <1992Apr10.175811.7669@cc.umontreal.ca>, casgrain@ERE.UMontreal.CA (Casgrain Philippe) writes: > > > I would like to know how to turn file sharing ON or OFF, not by > using the Control Panel, but from within an application. See Tech Note 305. - -- Larry Rosenstein Taligent, Inc. lsr@taligent.com +++++++++++++++++++++++++++ From: roy@adeptsln.cts.com Date: 14 Apr 92 03:37:29 GMT Organization: Adept Solutions In article <kucjcjINN4jl@alshain.usc.edu> lkimes@alshain.usc.edu (Lance 'Moof' Kimes) writes: > > In article <D88-JWA.92Apr11002621@byse.nada.kth.se>, d88-jwa@byse.nada.kth.se (Jon W{tte) writes: > |> .umontreal.ca> casgrain@ERE.UMontreal.CA (Casgrain Philippe) writes: > |> > |> I would like to know how to turn file sharing ON or OFF, not by > |> using the Control Panel, but from within an application. > |> There seems to be no mention of this in IM VI. > |> > |> OFF: Send a quit apple event to the File Sharing process. > |> ON: LaunchApplication on the File Sharing extension. > |> > |> FindFolder, PBCatSearch, GetNextProcess, GetProcessInfo and the > |> AE manager seems to be the parts you need. > |> > |> -- > |> h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! > > > Have you tried this to see if it works? It seems to me to be both very useful & > full of potential security hazards. > > I know all users should be setup already with names & passwords, but what about hte clueless who are not? Even if everythings passworded, sharing could be turned on AGAINST your wishes & compromised passwords then allow easy entry. > > > I guess we're just paranoid at USC, but we're safe. :-) > > Lance Kimes > USC What security hazard? The Apple Event is being sent FROM THE SAME MACHINE that filesharing is on. (Program sharing has it's own password setup). Sharing isn't being turned on against YOUR wishes because YOU are on the machine! Unless you are paranoid about turning it on, yourself. It's just an alternate way, other than the Control Panel. Lance, maybe you can specify what you are paranoid about, because it seems completely tame. - -- Roy Lovejoy | internet: roy@adeptsln.cts.com Head RGB Guy | AppleLink: adept Adept Solutions | CIS: 72447,1447 .................| dual certified developer: NeXT & Apple ;) --------------------------- From: krk@itl.itd.umich.edu (Kenneth Knight) Subject: Mapping one color to another - help! Organization: Instructional Technology Laboratory, University of Michigan Date: Tue, 14 Apr 92 12:08:24 GMT I need some more help.... I am writing a image processing tool that will re-map one color to another. Specifically, all the pixels in an image (32 bit deep GWorld) of the specified color will have their color changed to the current foreground color. I thought that using the SetEntries() toolbox call to modify the 32-bit deep GWorld's CLUT would make sense, but I can not figure out where the current color, the one that will be changed, is in the CLUT. Nor am I sure just what goes in the CSpecArray.value field. IM V says that SetEntries only works with 16-bit value integers and this also strikes me as wrong since that would limit a CLUT to 128k worth of colors and in a 32-bit deep GWorld we have many more than that. How do I perform this color re-mapping? Thanks ** Ken ** krk@itl.itd.umich.edu +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Tue, 14 Apr 1992 13:06:08 GMT krk@itl.itd.umich.edu (Kenneth Knight) writes: > >...all the pixels in an image (32 bit deep GWorld) of the specified >color will have their color changed to the current foreground color. I thought >that using the SetEntries() toolbox call to modify the 32-bit deep GWorld's >CLUT would make sense, but I can not figure out where the current color, the >one that will be changed, is in the CLUT. A 32-bit-deep graphics image stores the color values directly, and doesn't need a color lookup table. I'll bet there isn't a CLUT there, or if there is, changing it probably won't do you any good. Try checking out (**GetGWorldDevice(yourGWorld)).gdType. CLUT devices return 0; yours should be 2. Read the chapter on Graphics Devices for more info (IM6's is better than IM5's, it talks about GWorlds). You'll probably want to just scan through the data a longword at a time, reading in a pixel and changing it if it matches the proper color. - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy Ceci n'est pas une .signature. +++++++++++++++++++++++++++ From: russotto@eng.umd.edu (Matthew T. Russotto) Date: Tue, 14 Apr 92 15:21:06 GMT Organization: College of Engineering, University of Maryland, College Park In article <1992Apr14.120824.12158@terminator.cc.umich.edu> krk@itl.itd.umich.edu (Kenneth Knight) writes: >I need some more help.... > >I am writing a image processing tool that will re-map one color to another. >Specifically, all the pixels in an image (32 bit deep GWorld) of the specified >color will have their color changed to the current foreground color. I thought >that using the SetEntries() toolbox call to modify the 32-bit deep GWorld's >CLUT would make sense, but I can not figure out where the current color, the >one that will be changed, is in the CLUT. Nor am I sure just what goes in >the CSpecArray.value field. 32-bit GWorlds do NOT have useful color tables. They are 'direct mapped', meaning each pixel value is $aarrggbb, where a = alpha channel, r = red, g = green, b = blue. The color table is ignored. You have to iterate through the values in the pixmap and actually change the pixel values. - -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu Some news readers expect "Disclaimer:" here. Just say NO to police searches and seizures. Make them use force. (not responsible for bodily harm resulting from following above advice) +++++++++++++++++++++++++++ From: krk@itl.itd.umich.edu (Kenneth Knight) Date: 15 Apr 92 17:01:59 GMT Organization: Instructional Technology Laboratory, University of Michigan In article <1992Apr14.152106.5674@eng.umd.edu> russotto@eng.umd.edu (Matthew T. Russotto) writes: >In article <1992Apr14.120824.12158@terminator.cc.umich.edu> krk@itl.itd.umich.edu (Kenneth Knight) writes: >>I need some more help.... >> >>I am writing a image processing tool that will re-map one color to another. >>Specifically, all the pixels in an image (32 bit deep GWorld) of the specified >>color will have their color changed to the current foreground color. I thought >>that using the SetEntries() toolbox call to modify the 32-bit deep GWorld's >>CLUT would make sense, but I can not figure out where the current color, the >>one that will be changed, is in the CLUT. Nor am I sure just what goes in >>the CSpecArray.value field. > >32-bit GWorlds do NOT have useful color tables. They are 'direct >mapped', meaning each pixel value is $aarrggbb, where a = alpha >channel, r = red, g = green, b = blue. The color table is ignored. >You have to iterate through the values in the pixmap and actually >change the pixel values. Alright, as an aside. I managed to do what I needed with a costum search proc (and the documentation on those is really wierd. I am not quite sure what the result param is for...). I followed a standard one I found and it works, but it only works for GWorld's that are 32 bits deep. I applied it to the same GWorld set to 8 bits deep and nothing happened. Ideas anyone? (Hey, Matthew, nice to see you are still around. Tell everyone else I am too....and it might be that the U.M. cops would get along with you EVEN BETTER than UMCP's...) --------------------------- From: cmp9116@sys.uea.ac.uk (A. Coats) Subject: refreshing a colour screen Date: 14 Apr 92 12:34:30 GMT Pleae could someone help me on the subject of refreshing a screen after it has been overwritten when a dialog box has been displayed. I have no representation of what is on the screen, so redrawing it is a long process. I have tried bitmaps, pixmaps, and offscreen drawing (using Apples Tech. note 120, but falls over on the For loop, and messes up the colour). If anyone could tell me how to copy the screen pixels to a pixel map, and then copying it back again with the colour info. intact. Thanks in advance. David, via Andy, UEA - Norwich. +++++++++++++++++++++++++++ From: krk@itl.itd.umich.edu (Kenneth Knight) Date: 15 Apr 92 17:34:59 GMT Organization: Instructional Technology Laboratory, University of Michigan In article <cmp9116.703254870@s1.sys.uea.ac.uk> you write: >Pleae could someone help me on the subject of refreshing a screen >after it has been overwritten when a dialog box has been displayed. >I have no representation of what is on the screen, so redrawing it is >a long process. I have tried bitmaps, pixmaps, and offscreen drawing >(using Apples Tech. note 120, but falls over on the For loop, and messes >up the colour). If anyone could tell me how to copy the screen pixels >to a pixel map, and then copying it back again with the colour info. >intact. Very quickly. You will generaly do all drawing to a screen in one routine - the routine that is called when an update event takes place. Up to that point most times you will do your drawing in an offscreen graphic's world or repre- sent it with some meta-language or some other mains depending on what you deem best. In order to get the udpate events you have to invalidate the rectangle (or region) that needs to be re-drawn. For simplicities sake just invalidate the whole portRect of the window (I assume that is what you have) that got covered by the dialog (naturally, it is better just to invalidate the part that needs to be re-drawn). The call you need for this is InvalRect(). Let's assume you are doing all your drawing to an 8-bit deep off screen GWorld that you've made with NewGWorld (IM VI and note 120, and other places). You've been very good about being sure to draw into that world (i.e. Get/Set-GWorld calls in the right places and you do Lock/Unlock-Pixles() calls before and after you do any drawing into this GWorld as you should). To draw that GWorld to the screen you would do something like this (in your function that handles update events): if (theWindow /* WindowPtr passed in */ == windowToUpdate) { BeginUpdate(theWindow); EraseRect(&(theWindow->portRect)); /* clear it all out. */ DrawControls(theWindow); /* if you have 'em. */ DrawGrowIcon(theWindow); /* ditto */ CopyBits(&((GrafPtr)drawWorld)->portBits, &((GrafPtr)theWindow)->portBits, &(theWindow->portRect), &(theWindow->portRect), srcCopy, nil); EndUpdate(theWindow); The CopyBits() is the key call. It copies the offscreen GWorld to you window. To be perfectly safe you should make sure that the foreground color is black and background color is white (of the current grafport). This will let you avoid any potental colorizing problems. Hope this helps (I am in a rush...)... --------------------------- From: kevin@crash.cts.com (Kevin Hill) Subject: How to Get the Name of A File? Date: 14 Apr 92 10:42:26 GMT Organization: Crash TimeSharing, El Cajon, CA I am on the home stretch of my new program!! BUT! I am using the class library of THink C Ok here's the problem: I have the DirID of the directory. I have the volNum of the directory. I don't have the name of the file. (problem) I tried to use GetMacFileInfo to get the Finfo struct that would contain the name and type etc.. However, I get a -43 error. Other problem. when I use ioFDirIndex to get the files in the directory, I again cannot figure out how to get the name of the files in the directory. GetMacFileInfo again does not work, it crashes with -43 error. yuk.. any help would be appreciated. -Kevin +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Tue, 14 Apr 1992 15:18:00 GMT kevin@crash.cts.com (Kevin Hill) writes: > > I am on the home stretch of my new program!! BUT! > > Ok here's the problem: > > I have the DirID of the directory. > I have the volNum of the directory. > I don't have the name of the file. (problem) > > I tried to use GetMacFileInfo to get the Finfo struct that would contain >the name and type etc.. However, I get a -43 error. > >when I use ioFDirIndex to get the files in the directory, >I again cannot figure out how to get the name of the files >in the directory. GetMacFileInfo again does not >work, it crashes with -43 error. I'm not sure I understand. This is the same problem, right? If you have the dirID and volNum, you need one more piece of information to get at the file, and if you don't know the name, it must be the dirIndex. So you're trying to use a dirIndex to find your file? CFile::GetMacFileInfo() relies on having the name of the file set up properly; it won't help you if you haven't specified the file. Here's a little sample code that cycles through a directory. I use GetCatInfo, but the idea's the same. Str63 myName; OSErr theOSErr; CInfoPBRec myPB; myPB.hFileInfo.ioCompletion = NULL; myPB.hFileInfo.ioNamePtr = myName; myPB.hFileInfo.ioVRefNum = vRefNum; myPB.hFileInfo.ioFrIndex = 1; while (theOSErr == noErr) { Boolean isFile; myName[0] = 0; myPB.hFileInfo.ioDirID = dirID; // see IM4 p126. theOSErr = PBGetCatInfo(&myPB, FALSE); if (theOSErr == fnfErr || theOSErr == nsvErr) { break; } else if (theOSErr != noErr) { Debugger(); break; } isFile = (BitTst(&myPB.dirInfo.ioFlAttrib, 3) == 0); if (isFile) { FInfo *theFInfo; theFInfo = &myPB.hFileInfo.ioFlFndrInfo; } ++myPB.hFileInfo.ioFDirIndex; } That call to Debugger() is in there because I don't think any error should be returned except an fnfErr (which indicates that there are no more files in the directory) or an nsvErr (which would indicate a bad vRefNum or dirID). Note that you have to reset dirID each time through. Contrary to a comment in the UMPG Volume I, there _is_ a reference to this in IM; it's just very well hidden. :-) - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy "Almost all portables today employ passive-matrix LCDs, and no one expects active-matrix screens to be cost-competitive for a few years" -PC World 2/92 +++++++++++++++++++++++++++ From: mspace@netcom.com (Brian Hall) Date: 15 Apr 92 00:22:26 GMT Organization: Netcom - Online Communication Services (408 241-9760 guest) In article <1992Apr14.104226.1649@crash.cts.com> kevin@crash.cts.com (Kevin Hill) writes: > I am using the class library of THink C > > Ok here's the problem: > > I have the DirID of the directory. > I have the volNum of the directory. > I don't have the name of the file. (problem) > Why not call CDataFile::GetName to get the name? - -- +-----------------------------------------------------------------------------+ | Brian Hall, Mark/Space Softworks | | mspace@netcom.com; Applelink, America Online: MarkSpace | +-----------------------------------------------------------------------------+ --------------------------- From: erh0362@tesla.njit.edu Subject: Register variables in Think C 4.05 Date: 14 Apr 92 14:45:12 GMT Organization: New Jersey Institute of Technology How intelligent is Think C 4.05 about assigning variables to registers? Will declaring my frequently used variables as register offer significant improvements or should I rely on Think C to do this for me? Elliotte Rusty Harold Department of Applied Mathematics elharo@m.njit.edu New Jersey Institute of Technology erh0362@tesla.njit.edu Newark, NJ 07103 +++++++++++++++++++++++++++ From: phils@chaos.cs.brandeis.edu (Phil Shapiro) Date: 15 Apr 92 14:40:00 GMT Organization: Symantec Corp. >>>>> On 14 Apr 92 14:45:12 GMT, erh0362@tesla.njit.edu said: > How intelligent is Think C 4.05 about assigning variables to > registers? Will declaring my frequently used variables as register > offer significant improvements or should I rely on Think C to do > this for me? C 4.0.x does *not* do any register allocation. If you want your locals to be placed in registers, you must declare them with the register keyword. C 5.0 does support register allocation, however. If you use the register keyword carefully (and probably even not carefully) in C 4.0, you can get a fair amount of improvement in code size and most likely code speed. -phil - -- Phil Shapiro Software Engineer Language Products Group Symantec Corporation Internet: phils@cs.brandeis.edu --------------------------- From: umsfjban@bill.oscs.montana.edu (Jeff Banfield) Subject: Problem De-allocating Memory in variable sized arrays Date: 1 Apr 92 22:26:46 GMT Organization: Montana State University, Bozeman MT I have a problem in de-allocating memory that I have allocated using NewPtr. I'm working on some image analysis software so I need to use some large dynamically allocated arrays. I'm using a Mac variation of the approach described in Numerical Recipes in C which basically allocates pointers to the rows and then allocates memeory for each row. Everything seems to work fine ... I can allocate the array, I can fill it up with numbers and I can plot it or numerically manipulate the array. If I de-allocate the array right after I create it the memory is freed up just like should be, but if use it, like filling it up wih numbers then I can't de-allocate it. I'm new to both C and MacIntosh Programming so I may be missing something obvious. I've learned more about the heap and the stack over the last few days than I ever wanted to know ... but maybe it's not enough. I'm using Think C 5.0. Here's the code ... this is the most recent incarnation, I've tried several variations to see if I can solve the problem (I'm typing it in at the terminal so don't flame me if I forget a ; ...) Any suggestions on improving the implementation (yes I know I should check for succesful allocation) or style are welcome. global variables: unsigned char **DATA; int NROW, NCOL; void allocateDATA (void) { register i; DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); DATA -= 1; /* to allow indexing starting at 1 */ for (i = 1; i <= NROW; i++){ DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); DATA[i] -= 1; /* to allow indexing starting at 1 */ } } void freeDATA (void) { register i; for (i = 1; i <= NROW; i++){ DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ } DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ } If I give the command: allocateDATA(); .... then check the heap size it's gone down the appropriate amount If I now give the command freeDATA(); .... and now check the heap size it's increased the appropriate amount However if I give the commands allocateDATA(); ... heap size decreases fillDATA(); ... which runs through the open file dialog, reads in a file and puts ... the results into DATA, the heap size doesn't change ... which it's ... not supposed to do since I've already allocated the memory. Now if I call freeDATA(); ... and check the heap size it doesn't change ... it's as though I never ... freed the data. Any suggestions or comments would be greatly appreciated. Jeff Banfield umsfjban@bill.oscs.montana.edu +++++++++++++++++++++++++++ From: Steve Creps <creps@silver.ucs.indiana.edu> Organization: Indiana University Date: Mon, 6 Apr 1992 10:37:35 -0500 In article <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: >I have a problem in de-allocating memory that I have allocated using >NewPtr. I'm working on some image analysis software so I need to >unsigned char **DATA; >int NROW, NCOL; > >void allocateDATA (void) >{ > register i; > > DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); > DATA -= 1; /* to allow indexing starting at 1 */ > > for (i = 1; i <= NROW; i++){ > DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); > DATA[i] -= 1; /* to allow indexing starting at 1 */ > } >} > >void freeDATA (void) >{ > register i; > > for (i = 1; i <= NROW; i++){ > DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ > } > DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ >} First I would ask (not a flame) why you want to start the array indices at 1 instead of zero? You said you are new to C, so you may not yet have found that arrays nearly always start at 0 in C programs. IMO it's better to start doing (and getting used to) zero-based arrays sooner than later. I strongly suspect that your problem has something to do with the way you are manipulating DATA (e.g. adding and subtracting). I suggest changing the program to start the array at zero (remember to change "i <= NROW" to "i < NROW"). I'm not absolutely sure that that will fix it, but one experiment is worth a thousand theories. Anyway, you probably don't want to be incrementing and decrementing pointers. This practice often works, but it is not guaranteed that it always will. Your mileage may vary, depending on operating system, compiler, and the data types involved. - - - - - - - - - - - Steve Creps, Indiana University creps@silver.ucs.indiana.edu (129.79.1.6) {inuxc,rutgers,uunet!uiucdcs,pur-ee}!iuvax!silver!creps +++++++++++++++++++++++++++ From: sgrenander@nasamail.jpl.nasa.gov (Sven Grenander) Date: 6 Apr 92 20:47:52 GMT Organization: Jet Propulsion Laboratory In article <1992Apr6.103745.28462@bronze.ucs.indiana.edu>, Steve Creps <creps@silver.ucs.indiana.edu> writes: > > In article <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: > >I have a problem in de-allocating memory that I have allocated using > >NewPtr. I'm working on some image analysis software so I need to > > >unsigned char **DATA; ......... > > > > for (i = 1; i <= NROW; i++){ > > DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ > > } > > DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ > >} > > First I would ask (not a flame) why you want to start the array indices at > 1 instead of zero? You said you are new to C, so you may not yet have found > that arrays nearly always start at 0 in C programs. IMO it's better to start > doing (and getting used to) zero-based arrays sooner than later. ........ > > The problem with zero-based arrays is that most (?) mathematical routines have been developed for one-based arrays, but that's just an aside. If you look in "Mathematical Recipes In C" they provide routines for allocating and freeing arrays. The routines work, I use them (with minor modifications) but may not represent the best C implementations as they do things like SHIFT rather than divide by 2 etc. - - Sven +++++++++++++++++++++++++++ From: Steve Creps <creps@silver.ucs.indiana.edu> Organization: Indiana University Date: Mon, 6 Apr 1992 10:37:35 -0500 In article <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: >I have a problem in de-allocating memory that I have allocated using >NewPtr. I'm working on some image analysis software so I need to >unsigned char **DATA; >int NROW, NCOL; > >void allocateDATA (void) >{ > register i; > > DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); > DATA -= 1; /* to allow indexing starting at 1 */ > > for (i = 1; i <= NROW; i++){ > DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); > DATA[i] -= 1; /* to allow indexing starting at 1 */ > } >} > >void freeDATA (void) >{ > register i; > > for (i = 1; i <= NROW; i++){ > DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ > } > DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ >} First I would ask (not a flame) why you want to start the array indices at 1 instead of zero? You said you are new to C, so you may not yet have found that arrays nearly always start at 0 in C programs. IMO it's better to start doing (and getting used to) zero-based arrays sooner than later. I strongly suspect that your problem has something to do with the way you are manipulating DATA (e.g. adding and subtracting). I suggest changing the program to start the array at zero (remember to change "i <= NROW" to "i < NROW"). I'm not absolutely sure that that will fix it, but one experiment is worth a thousand theories. Anyway, you probably don't want to be incrementing and decrementing pointers. This practice often works, but it is not guaranteed that it always will. Your mileage may vary, depending on operating system, compiler, and the data types involved. - - - - - - - - - - - Steve Creps, Indiana University creps@silver.ucs.indiana.edu (129.79.1.6) {inuxc,rutgers,uunet!uiucdcs,pur-ee}!iuvax!silver!creps +++++++++++++++++++++++++++ From: sgrenander@nasamail.jpl.nasa.gov (Sven Grenander) Date: 6 Apr 92 20:47:52 GMT Organization: Jet Propulsion Laboratory In article <1992Apr6.103745.28462@bronze.ucs.indiana.edu>, Steve Creps <creps@silver.ucs.indiana.edu> writes: > > In article <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: > >I have a problem in de-allocating memory that I have allocated using > >NewPtr. I'm working on some image analysis software so I need to > > >unsigned char **DATA; ......... > > > > for (i = 1; i <= NROW; i++){ > > DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ > > } > > DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ > >} > > First I would ask (not a flame) why you want to start the array indices at > 1 instead of zero? You said you are new to C, so you may not yet have found > that arrays nearly always start at 0 in C programs. IMO it's better to start > doing (and getting used to) zero-based arrays sooner than later. ........ > > The problem with zero-based arrays is that most (?) mathematical routines have been developed for one-based arrays, but that's just an aside. If you look in "Mathematical Recipes In C" they provide routines for allocating and freeing arrays. The routines work, I use them (with minor modifications) but may not represent the best C implementations as they do things like SHIFT rather than divide by 2 etc. - - Sven +++++++++++++++++++++++++++ From: d88-jwa@hemul.nada.kth.se (Jon W{tte) Date: 8 Apr 92 09:40:29 GMT Organization: Royal Institute of Technology, Stockholm, Sweden > harlan@copper.ucs.indiana.edu (Pete Harlan) writes: |>unsigned char **DATA; |> |> register i; |> |> DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); DATA is a pointer to NROW pointers to unsigned char. |> DATA -= 1; /* to allow indexing starting at 1 */ DATA is decreased one UNIT; where the unit is "pointer" in this case. Use DATA from 1 to NROW now, not 0 to NROW-1 |> for (i = 1; i <= NROW; i++){ See, he loops from 1 to NROW ! |> DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); Allocate NCOL chars |> DATA[i] -= 1; /* to allow indexing starting at 1 */ Decrease one unit. In this case, the unit is a char. Still OK. This is wrong-o, forget the deallocation, you've stomped on memory already. Go back to K&R, do not pass GO, an no $200. Why ? I see exactly nothing wrong with this. |> for (i = 1; i <= NROW; i++){ |> DisposPtr(DATA[i] + 1); /* + 1 because of index starting at 1 */ |> } |> DisposPtr(DATA + 1); /* + 1 because of index starting at 1 */ This is even worse... Again, why ? He decreased the pointers after assigning them, now he's increasing them to get back the old values. program displays such a magnificent lack of understanding about C pointers that no quick fix should be attempted, despite the fact that a couple of quick changes will indeed fix this bit (though who knows about the rest of the program?) Okay, I've hacked C for more than six years. I've done stuff not unlike this myself, and it worked. Have I gotten my C all backward ? Not flaming anyone here; C pointers are tricky indeed... Not especially, after the first two years or so... Again, I quote you: already. Go back to K&R, do not pass GO, an no $200. Are you sure it's the original poster who should go back to K&R. If he should, I should too, it seems. - -- h+@nada.kth.se; Jon W{tte, the Diplomat - NOT! +++++++++++++++++++++++++++ From: Pete Harlan <harlan@copper.ucs.indiana.edu> Organization: Indiana University Date: Wed, 8 Apr 1992 05:25:53 -0500 [Note: I followed up to this article once already in a totally idiotic fashion, not having properly examined the code. I cancelled it, but if you read it please ignore it...] In <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: |void allocateDATA (void) |{ | register i; | DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); | DATA -= 1; /* to allow indexing starting at 1 */ | for (i = 1; i <= NROW; i++){ | DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); | DATA[i] -= 1; /* to allow indexing starting at 1 */ | } |} Okay, this is really pretty nifty, excepting for the fact, pointed out by Steve Creps, that having a pointer to the 'element' before the first element of an array might cause you problems (such as it wrapping around to being a huge number, but even that might not cause a problem). (Actually, since NewPtr probably has some housekeeping stuff before the actual allocated memory, as long as your element size is small enough I'm sure you'll be okay.) |However if I give the commands | allocateDATA(); |... heap size decreases | fillDATA(); |... which runs through the open file dialog, reads in a file and puts |... the results into DATA, the heap size doesn't change ... which it's |... not supposed to do since I've already allocated the memory. |Now if I call | freeDATA(); |... and check the heap size it doesn't change ... it's as though I never |... freed the data. It would seem as if there's a problem with your fillDATA() routine. Would it be possible, with real (e.g., not Think C) C++ to define a class that is a 1-based array, and define the various operators on it (e.g., [], dereferencing, +) so they would convert it back to 0-based, and also define the casts to and from 0-based arrays, so that it would be impossible to make a mistake when passing arrays to and from routines that operate on 1-based arrays? (The compiler would automatically convert if a routine that was declared to take an object of type 1-based-array were passed an ordinary C-based array, and vice-versa.) A friend has suggested doing this to interface code written to work with 1-based X-Y coordinates with routines that expect 0-based coordinates, and it seems that perhaps it could be beneficial here. Of course, sticking to the C paradigm of 0-based arrays will not only help your code work with more C code, but will also make it more readable to others (such as simpletons like myself who didn't look at it closely enough when you posted it). - --Pete Harlan harlan@copper.ucs.indiana.edu +++++++++++++++++++++++++++ From: erh0362@tesla.njit.edu Date: 14 Apr 92 14:18:29 GMT Organization: New Jersey Institute of Technology > In <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: > > |void allocateDATA (void) > |{ > | register i; > > | DATA = (unsigned char **) NewPtr(NROW * sizeof(unsigned char *)); > | DATA -= 1; /* to allow indexing starting at 1 */ > > | for (i = 1; i <= NROW; i++){ > | DATA[i] = (unsigned char *) NewPtr(NCOL * sizeof(unsigned char)); > | DATA[i] -= 1; /* to allow indexing starting at 1 */ > | } > |} > > Okay, this is really pretty nifty, excepting for the fact, pointed out > by Steve Creps, that having a pointer to the 'element' before the > first element of an array might cause you problems (such as it > wrapping around to being a huge number, but even that might not cause > a problem). (Actually, since NewPtr probably has some housekeeping > stuff before the actual allocated memory, as long as your element size > is small enough I'm sure you'll be okay.) (various comments deleted ) > Would it be possible, with real (e.g., not Think C) C++ to define a > class that is a 1-based array, and define the various operators on it > (e.g., [], dereferencing, +) so they would convert it back to 0-based, > and also define the casts to and from 0-based arrays, so that it would > be impossible to make a mistake when passing arrays to and from > routines that operate on 1-based arrays? (The compiler would > automatically convert if a routine that was declared to take an object > of type 1-based-array were passed an ordinary C-based array, and > vice-versa.) It's not only possible. It's a standard thing to do in certain circumstances. The trick that seems to be missed here is using two pointers instead of one. For instance to make an array of ints of dimension N that starts at index 1 do something like: int *temp, *myarray; temp = (int ) malloc(N * sizeof(int)); myarray = temp - 1; myarray now points to the element before temp. However you shouldn't actually dereference temp but instead use myarray[1] through myarray[N] to point to the appropriate elements. Using myarray[0] anywhere would cause untold havoc. This is all quite well documented in Numerical Recipes in C, along with routines to do similar things for multi-dimensional matrices. Elliotte Rusty Harold Department of Applied Mathematics elharo@m.njit.edu New Jersey Institute of Technology erh0362@tesla.njit.edu Newark, NJ 07103 +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Tue, 14 Apr 1992 15:30:34 GMT erh0362@tesla.njit.edu writes: >> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: >> >> |void allocateDATA (void) >> |{ >> | DATA -= 1; /* to allow indexing starting at 1 */ >> |} >> >> Okay, this is really pretty nifty, excepting for the fact, pointed out >> by Steve Creps, that having a pointer to the 'element' before the >> first element of an array might cause you problems... >> >> Would it be possible, with real (e.g., not Think C) C++ to define a >> class that is a 1-based array > > It's not only possible. It's a standard thing to do in certain >circumstances... > > int *temp, *myarray; > temp = (int ) malloc(N * sizeof(int)); > myarray = temp - 1; > >This is all quite well documented in Numerical Recipes in C, >along with routines to do similar things for multi-dimensional matrices. This will work on the Mac (currently), because pointers are always 32 bits, memory is contiguous, there's no memory protection, and everything is generally clean and tidy. But don't assume it's portable. From the comp.lang.c FAQ list: 2.10: Can I simulate a non-0-based array with a pointer? A: Not if the pointer points outside of the block of memory it is intended to access, contrary to an idiom used in Numerical Recipes in C. If a pointer points outside of an allocated block of memory, the behavior is undefined, _even if the pointer is not dereferenced_. (Explicit dispensation is granted, however, for a pointer that points to the location one past an array's last element.) References: ANSI Rationale Sec. 3.2.2.3 p. 38. [And see K&R 2nd ed. pp102-3 and 205 -- JRM] - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy "Glass of milk / Standing in between extinction in the cold And explosive radiating growth" - They Might Be Giants +++++++++++++++++++++++++++ From: karl@ima.isc.com (Karl Heuer) Organization: Interactive Systems, Cambridge, MA 02138-5302 Date: Tue, 14 Apr 1992 19:29:35 GMT In article <1992Apr14.091829.1@tesla.njit.edu> erh0362@tesla.njit.edu writes: >>In <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: >>[Can you fake a 1-based array using C++ classes?] Possibly, but I would avoid it if at all possible. >[Use malloc()-1, as is done in Numerical Recipes] It works in most cases on most architectures, but it's not legal C. See question 2.10 of the FAQ. Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint +++++++++++++++++++++++++++ From: haney@moonshine.llnl.gov (Scott W. Haney) Date: 14 Apr 92 22:11:59 GMT karl@ima.isc.com (Karl Heuer) writes: >In article <1992Apr14.091829.1@tesla.njit.edu> erh0362@tesla.njit.edu writes: >>>In <1992Apr1.222646.10433@coe.montana.edu> umsfjban@bill.oscs.montana.edu (Jeff Banfield) writes: >>>[Can you fake a 1-based array using C++ classes?] >Possibly, but I would avoid it if at all possible. Why avoid it? One can easily (well, relatively easily) construct portable, vectorizable matrix and vector classes using C++. I've done it as have a number of other people (see the recent discussion on comp.lang.c++). There is no kludging involved and it it is much easier to deal with 1-based arrays stored by columns since most of the scientific world still is based on Fortran. Scott - -- - ------------------------------------------------------------------------- Scott W. Haney || Lawrence Livermore N'Lab || The above views are haney@random.llnl.gov || P.O. Box 808; L-644 || mine and not neces- (510) 423-6308 || Livermore, CA 94550 || sarily LLNL's. +++++++++++++++++++++++++++ From: atbowler@thinkage.on.ca (Alan Bowler) Date: 15 Apr 92 17:10:13 GMT Organization: /etc/organization In article <1992Apr14.153034.18214@hobbes.kzoo.edu> k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: >erh0362@tesla.njit.edu writes: >> >> It's not only possible. It's a standard thing to do in certain >>circumstances... >> >> int *temp, *myarray; >> temp = (int ) malloc(N * sizeof(int)); >> myarray = temp - 1; >> >>This is all quite well documented in Numerical Recipes in C, >>along with routines to do similar things for multi-dimensional matrices. > >This will work on the Mac (currently), because pointers are always 32 >bits, memory is contiguous, there's no memory protection, and everything >is generally clean and tidy. But don't assume it's portable. It is true that this use of pointers is not sanctioned by the the standard. As the FAQ points out there may exist architectures and implementations where p = &array[0] - 1; might not give a useable pointer, so p[1] will not address array[0]. However, these machines are not all that common, and it may be legitimate to say that you are not interested in porting to them. "portability" is NOT an absolute value. It is a measure of how much effort it is to reuse the existing code versus how much effort to reimplement from scratch. It is affected by features of the new environment. No program is absolutely portable to all environments. (As a trivial example, by choosing a language, you restrict the code to environments that support that language.) Any program has a set of enviroments that it is easily ported to, and as a rule of thumb you should strive to make that set as large as possible. However, there are tradeoffs, and the larger the set of environments, the more time and effort goes into the programming and maintenance. It may well be a smart decision to decide that you are not interested in porting to certain environments. As an extreme case, if you are writing a compiler to produce code for a sewing machine, you probably are not worried about making the compiler itself run on the sewing machine, and so don't need to worry about the fact that there is no file system. A harder choice would be a compiler for a 36/72 bit machine. Is it worth worrying about making it run as a cross compiler from a 32 bit workstation. There would be would be a lot of overhead in writing routines to simulate the target machine arithmetic, and using routines instead of inline operators would have a performance penalty when running the compiler on the 36/72 bit machine. The tradeoffs are not clear. Certainly there are a number of coding practices that cost very little and widen the set of target machines. These should be used routinely. However, portability is not the only goal, and you need to consider the tradeoffs of wider portability versus the costs in extra code poorer performance etc. --------------------------- End of C.S.M.P. Digest **********************